﻿import json
import traceback

import requests
from flask import Blueprint, request, session, redirect,current_app,send_file
from utilsapp import utils
from utilsapp.mysql_con import db_insert,db_list
import subprocess
import shutil
import datetime
from datetime import timedelta, datetime
from utilsapp.common import   get_collection_name


bluePrint = Blueprint('openapi', __name__)


# 定义一个简单的路由
@bluePrint.route('/auth')
def auth():
    token = request.values.get('token', '')
    page = request.values.get('page', '')
    page = page if page else 'login'

    account = get_auth(token)

    # 执行重定向到'/hello'路由
    return redirect('/login?')


def get_auth(token):
    try:
        o = {
            "systemCode": '044221b7ccc04262a9353facd0553279',
            "token": token
        }
        res = requests.get(
            'http://171.221.216.84:18000/api/ivystar-user/api/getUserByToken', params=o, timeout=5)
        if res.status_code != 200:
            print('获取当前登录人请求失败', res.status_code)
            return None
        j = res.json()
        if j['success']:
            print('获取当前登录人信息失败', res.text)
            return j['data']['account']
        return None
    except Exception as e:
        print('login_token 异常', e)
        return None


# 记录运行状态
@bluePrint.route('/log', methods=["post"])
def run_log():
    add_model = {
        "type": 'INFO',
        "content": json.dumps(request.json),
        "title": 'RUNLOG',
    }
    db_insert("log", add_model)
    return utils.ok()


@bluePrint.route('/gxqd', methods=["get"])
def gxqd():
    # 使用subprocess执行命令
    try:

        result = subprocess.check_output(r'"C:\Program Files\Git\bin\git.exe" pull', shell=True,
                                         cwd=r'C:\ieplat\ieplat_pc', stderr=subprocess.STDOUT,
                                         universal_newlines=True)
        result += subprocess.check_output('npm i', shell=True, cwd=r'C:\ieplat\ieplat_pc', stderr=subprocess.STDOUT,
                                          universal_newlines=True)
        result += subprocess.check_output('npm run build', shell=True, cwd=r'C:\ieplat\ieplat_pc',
                                          stderr=subprocess.STDOUT,
                                          universal_newlines=True)
        result += subprocess.check_output('nginx -s reload', shell=True, cwd=r'C:\nginx-1.21.6\nginx-1.21.6',
                                          stderr=subprocess.STDOUT,
                                          universal_newlines=True)

        nowdate = datetime.now().strftime('%Y%m%d_%H%M_%S')

        # 压缩文件或文件夹为7z格式
        subprocess.run(
            [r'C:\Program Files\7-Zip\7z.exe', 'a', rf'C:\ieplat\ieplat_pc\dist\ieplat_html_{nowdate}.zip',
             r'C:\ieplat\ieplat_pc\dist'])

        source_file = rf'C:\ieplat\ieplat_pc\dist\ieplat_html_{nowdate}.zip'
        destination_directory = rf'D:\Cloudpan\pan\ieplat_html_{nowdate}.zip'

        # 使用shutil.move移动文件并强制替换目标文件
        shutil.move(source_file, destination_directory)
        keep_latest_files()
        print("命令执行结果：")
        return utils.ok(None, result)
    except subprocess.CalledProcessError as e:
        print("命令执行错误：")
        print(e.output)
        return utils.fail('命令执行错误')
    except Exception as ex:
        print("发生异常：")
        print(ex)
        return utils.fail('异常')


@bluePrint.route('/getqdbranch', methods=["get"])
def getqdbranch():
    try:
        result = subprocess.check_output(r'"C:\Program Files\Git\bin\git.exe" branch -r', shell=True,
                                         cwd=r'C:\ieplat\0dist\ieplat_pc', stderr=subprocess.STDOUT,
                                         universal_newlines=True)
        lines = result.splitlines()
        return utils.ok(list(set([l.split('/')[1] for l in lines])))
    except Exception as e:
        traceback.print_exc()


@bluePrint.route('/gxhd', methods=["get"])
def gxhd():
    # 使用subprocess执行命令
    try:
        result = subprocess.check_output(r'"C:\Program Files\Git\bin\git.exe" pull', shell=True,
                                         cwd=r'C:\ieplat\ieplat_api', stderr=subprocess.STDOUT,
                                         universal_newlines=True)
        print("命令执行结果：")
        return utils.ok(None, result)
    except subprocess.CalledProcessError as e:
        print("命令执行错误：")
        print(e.output)
        return utils.fail('命令执行错误', e.output)
    except Exception as ex:
        print("发生异常：")
        print(ex)
        return utils.fail('异常', str(ex))


@bluePrint.route('/buildexe', methods=["get"])
def getexe():
    try:
        if not current_app.redis.set('buildexe_lock',"1",nx=True,ex=60*10):
            return utils.fail('正在打包中...请完成后操作...')

        branch = request.args.get('branch', '')
        result = ''
        if branch:
            result = subprocess.check_output(fr'"C:\Program Files\Git\bin\git.exe" checkout {branch}', shell=True,
                                             cwd=r'C:\ieplat\0dist\ieplat_pc', stderr=subprocess.STDOUT,
                                             universal_newlines=True)
            branch = "_" + branch

        result_pc = subprocess.check_output(r'"C:\Program Files\Git\bin\git.exe" pull', shell=True,
                                          cwd=r'C:\ieplat\0dist\ieplat_pc', stderr=subprocess.STDOUT,
                                          universal_newlines=True)
        # if 'Already up to date' not in result_pc:
        result += subprocess.check_output('npm i', shell=True, cwd=r'C:\ieplat\0dist\ieplat_pc',
                                              stderr=subprocess.STDOUT,
                                              universal_newlines=True)
        result += subprocess.check_output('npm run build', shell=True,
                                              cwd=r'C:\ieplat\0dist\ieplat_pc',
                                              stderr=subprocess.STDOUT, universal_newlines=True)
        result_api = subprocess.check_output(r'"C:\Program Files\Git\bin\git.exe" pull', shell=True,
                                          cwd=r'C:\ieplat\0dist\ieplat_api',
                                          stderr=subprocess.STDOUT,
                                          universal_newlines=True)
        if 'Already up to date' not in result_api:
            result += subprocess.check_output(
                r'C:\Users\Administrator\AppData\Local\Programs\Python\Python39\python.exe -m pip install -r C:\ieplat\0dist\ieplat_api\requirements.txt',
                shell=True,
                cwd=r'C:\ieplat\0dist\ieplat_api',
                stderr=subprocess.STDOUT,
                universal_newlines=True)
        result += subprocess.check_output(
            r'C:\Users\Administrator\AppData\Local\Programs\Python\Python39\Scripts\pyinstaller.exe main2.spec',
            shell=True,
            cwd=r'C:\ieplat\0dist\ieplat_api',
            stderr=subprocess.STDOUT,
            universal_newlines=True)

        nowdate = datetime.now().strftime('%Y%m%d_%H%M_%S')

        source_file = rf'C:\ieplat\0dist\ieplat_api\dist\ieplat_api{branch}_{nowdate}.zip'

        # 压缩文件或文件夹为7z格式
        subprocess.run(
            [r'C:\Program Files\7-Zip\7z.exe', 'a', source_file,
             r'C:\ieplat\0dist\ieplat_api\dist\ieplat.exe',
             r'C:\ieplat\0dist\ieplat_api\dist\config.json', r'C:\ieplat\0dist\ieplat_api\dist\static'])

        destination_directory = rf'C:\ieplat\api\static\store\部署包\ieplat_api{branch}_{nowdate}.zip'

        # 使用shutil.move移动文件并强制替换目标文件
        shutil.move(source_file, destination_directory)
        keep_latest_files()
        url = 'http://kf.demo.com/upload1'  # 你要上传文件的目标URL
        file_path = destination_directory  # 要上传的文件路径
        files = {'file': open(file_path, 'rb')}  # 指定文件参数名为 'file'
        response = requests.post(url, files=files)
        print('response',response.text)
        print(branch)
        print("命令执行结果：",result)
        return utils.ok('打包完成,请在http://kf.demo.com下载')
    except subprocess.CalledProcessError as e:
        print("命令执行错误：")
        print(e.output)
        return utils.fail('命令执行错误')
    except Exception as ex:
        print("发生异常：")
        print(ex)
        return utils.fail('异常')
    finally:
        current_app.redis.delete('buildexe_lock')


@bluePrint.route('/deviceadd', methods=["post"])
def deviceadd():
    print(1)


@bluePrint.route('/test', methods=["get"])
def test():
    t = session['ttt'] if type(session['ttt']) == int else 0
    session['ttt'] = 1 + t
    return utils.ok(session['ttt'])


@bluePrint.route('/test1', methods=["get"])
def test1():
    print(session.get('ttt', 0))
    return utils.ok(session.get('ttt', 0))


import os
import fnmatch
from collections import defaultdict

def keep_latest_files(num_to_keep=2):
    patterns = ["ieplat_api*", "ieplat_html*"]
    file_dict = defaultdict(list)

    # 遍历目录，将文件按照模式分类并保存最新的两个文件
    for root, dirs, files in os.walk("D:/Cloudpan/pan"):
        for pattern in patterns:
            matching_files = fnmatch.filter(files, pattern)
            for file in matching_files:
                file_path = os.path.join(root, file)
                file_dict[pattern].append((file_path, os.path.getmtime(file_path)))

    # 删除除了最新的两个文件之外的文件
    for pattern, files in file_dict.items():
        files.sort(key=lambda x: x[1], reverse=True)
        files_to_delete = files[num_to_keep:]

        for file_path, _ in files_to_delete:
            print(f"Deleting file: {file_path}")
            os.remove(file_path)



@bluePrint.route('/sensor/list', methods=["get"])
def get_sensor_list():
    sql = '''
    select concat(a.sensor_name,'-',tb.`name`) as pointName,CONCAT(a.`port`,a.address,'-',tb.`index`) as pointCode,
    a.fs as frequency,a.device_id as componentId,b.device_name as position,tb.pointUnit,tb.dataType 
		,tb.`index`
		 from sensor a
    LEFT JOIN device b on a.device_id=b.id
		LEFT JOIN 
(SELECT 0 as `id`, 0 as `index`, '有效值' as `name`, 'acc_rms' as `key`,5 as pointUnit,2 as dataType UNION ALL 
SELECT 0 as `id`, 1,'温度' as `name`, 'tem',2,1 UNION ALL 
SELECT 0 as `id`, 2,'裕度指标' as `name`, 'acc_cle',0,2 UNION ALL 
SELECT 0 as `id`, 3,'均值' as `name`, 'acc_mean',5,2 UNION ALL 
SELECT 0 as `id`, 4,'最大值' as `name`, 'acc_max',5,2 UNION ALL 
SELECT 0 as `id`, 5,'最小值' as `name`, 'acc_min',5,2 UNION ALL 
SELECT 0 as `id`, 6,'峰峰值' as `name`, 'acc_pp',5,2 UNION ALL 
SELECT 0 as `id`, 7,'方根幅值' as `name`, 'acc_root',5,2 UNION ALL 
SELECT 0 as `id`, 8,'平均幅值' as `name`, 'acc_ave',5,2 UNION ALL 
SELECT 0 as `id`, 9,'波形指标' as `name`, 'acc_sha',0,2 UNION ALL 
SELECT 0 as `id`, 10, '峰值指标' as `name`, 'acc_cre',0,2 UNION ALL 
SELECT 0 as `id`, 11, '歪度指标' as `name`, 'acc_ske',0,2 UNION ALL 
SELECT 0 as `id`, 12, '脉冲指标' as `name`, 'acc_imp',0,2 UNION ALL 
SELECT 0 as `id`, 13, '峰值' as `name`, 'acc_peak',5,2 UNION ALL 
SELECT 0 as `id`, 14, '峭度指标' as `name`, 'acc_kur',0,2 UNION ALL 
SELECT 0 as `id`, 15, '波形数据' as `name`, '',0,6)
 tb  on tb.`id`=0
    '''
    return db_list(sql)


def get_sensors():
    sql = '''
    SELECT s.id,s.sensor_name,s.address,s.`port`,s.device_id,direction,s.sensor_type,s.group_id,
r1.`name` name1,r2.`name` name3,r3.`name` name4,r4.`name` name2,d.device_name FROM sensor s
LEFT JOIN regionlevel r1 on r1.id=s.group_id
LEFT JOIN regionlevel r2 on r2.id=s.factory_id
LEFT JOIN regionlevel r3 on r3.id=s.zone_id
LEFT JOIN regionlevel r4 on r4.id=s.company_id
LEFT JOIN device d on d.id=s.device_id
    '''
    return db_list(sql)['data']


@bluePrint.route('/sensor/checks', methods=["get"])
def get_sensor_checks():
    try:
        now_time = datetime.now()
        proj_no = request.args.get('projno', '0001')

        db = current_app.mgdb[f"ieplat_{proj_no}"]
        sensors = get_sensors()
        rs = []
        err_sensors = []
        if os.path.exists('output.txt'):
            os.remove('output.txt')

        sbs = []

        sbs.append(f'<tr><td>测点编号</td><td width="180px">工厂名称</td><td width="180px">区域名称</td><td width="180px">设备名称</td><td width="180px">测点名称</td><td width="180px">特征值时间(最新三条)</td><td width="180px">波形时间(最新三条)</td><td width="120px">振动速度(最新三条)</td><td width="120px">温度(最新三条)</td><td width="120px">转速(最新三条)</td><td width="120px">信号强度(最新三条)</td><td width="120px">电压(最新三条)</td><td width="120px">电流(最新三条)</tr></td>')
        with open('output.txt', 'a', encoding='utf-8') as file:

            for t in sensors:
                try:
                    mg_addr = t['address'] if '_' in t['address'] else f"{t['address']}_0"
                    id_stime = int((now_time - timedelta(days=360)).timestamp())
                    id_etime = int(now_time.timestamp())

                    query_eige = {"$and": [{"_id": {"$gte": f"{t['port']}_{mg_addr}_{id_stime}"}},
                                            {"_id": {"$lte": f"{t['port']}_{mg_addr}_{id_etime}"}}, ]}
                    query_wave = {"$and": [{"_id": {"$gte": f"{t['port']}_{mg_addr}_Z_{id_stime}"}},
                                            {"_id": {"$lte": f"{t['port']}_{mg_addr}_Z_{id_etime}"}}, ]}
                    dbname = get_collection_name(db,f"eige_{t['port']}_{mg_addr.split('_')[0]}")
                    eiges = list(db[dbname].find(query_eige, {"_id": 1, "data.Z.vel_rms": 1, "data.tem": 1, "data.rssi": 1, "data.voltage": 1, "data.a_cur": 1})
                                    .sort('_id', -1).limit(3))
                    waves = list(db['wave'].find(
                        query_wave, {"_id": 1}).sort('_id', -1).limit(3))
                    tems=[]
                    rpms=[]
                    rssis=[]
                    voltages=[]
                    a_curs=[]
                    rmss=[]
                    tts=[]
                    wave_s = []
                    for eige in eiges:
                        tt = datetime.fromtimestamp(int(eige['_id'][-10:])).strftime('%Y-%m-%d %H:%M:%S')
                        tts.append(tt)
                        md = eige['data'].get('Z', None)
                        tem = eige['data'].get('tem', None)
                        if tem is not None:
                            tems.append(str(tem))
                        rpm = eige['data'].get('rpm', None)
                        if rpm is not None:
                            rpms.append(str(rpm))
                        rssi = eige['data'].get('rssi', None)
                        if rssi is not None:
                            rssis.append(str(rssi))
                        voltage = eige['data'].get('voltage', None)
                        if voltage is not None:
                            voltages.append(str(voltage))
                        a_cur = eige['data'].get('a_cur', None)
                        if a_cur is not None:
                            a_curs.append(str(a_cur))
                        rms = md.get('vel_rms', None) if md is not None else None
                        if rms is not None:
                            rmss.append(str(rms))
                    for w in waves:
                        wave_s.append(datetime.fromtimestamp(int(w['_id'][-10:])).strftime('%Y-%m-%d %H:%M:%S'))
                    msg = f"<tr><td>{t['port']}_{mg_addr}</td><td>{t['name3']}</td><td>{t['name4']}</td><td>{t['device_name']}</td><td>{t['sensor_name']}</td><td>{'、'.join(tts)}</td><td>{'、'.join(wave_s)}</td><td>{'、'.join(rmss)}</td><td>{'、'.join(tems)}</td><td>{'、'.join(rpms)}</td><td>{'、'.join(rssis)}</td><td>{'、'.join(voltages)}</td><td>{'、'.join(a_curs)}</td></tr>"
                    sbs.append(msg)
                    file.write(msg)  # 写入一行并添加换行符
                    # print(f"{t['port']}_{mg_addr}",'done.')
                except Exception as e:
                    traceback.print_exc()
        txt = "<table>"+''.join(sbs)+"</table>"

        return txt,200
    except Exception as e:
        return str(e), 500  # 返回文本和状态码

@bluePrint.route('/aes', methods=["get","post"])
def aes():
    id = request.args.get('id', '')
    v = utils.base64_encode(utils.aes_encrypt(id))
    return utils.ok(v)

